home *** CD-ROM | disk | FTP | other *** search
-
- ; A86 source code for VIEW.COM v2.1
-
- BUFFER EQU 0600 ;allow 2k for code + data + stack
- HALF_READ EQU 07C00 ;31k = half read buffer
- FULL_READ EQU HALF_READ + HALF_READ
- BUFFER_TOP EQU BUFFER + FULL_READ
- SHIFT EQU 16 ;right arrow key shift
-
- ORG 0100
- JMP SHORT START
-
- VIDEO_ADDR DW 'DD'
- VIDEO_SEG DW 0B800
- PLACE_MARK DW BUFFER
-
- SCR_ROWS DW 0
- CGA_MODE DB 0
-
- NO_FILE DB 'No File$'
- NO_MEMORY DB 'Out of RAM$'
-
- START: CLD
- CMP SP, 65530 ;FFFE = 65,534
- JAE PARSE
- MOV DX, OFFSET NO_MEMORY
- QUIT: MOV AH, 9
- INT 021
- INT 020
-
- PARSE: MOV SI, 081 ;point to command line parameters
- L1: LODSB ;load into AL, increase SI
- CMP AL, 020 ;space?
- JE L1 ;then skip
- CMP AL, 0D ;carriage return?
- JE FILE_ERROR
- CMP AL, '/' ;possible delimiter
- JNE OPEN_FILE
- LODSB
- AND AL, 0DF
- MOV W[PATCH], 020CD ;modify code - INT 020
- CMP AL, 'R' ;redirect
- JNE FILE_ERROR
-
- XOR BX, BX
- MOV AH, 045 ;duplicate file handle
- INT 021
- MOV W[FILE_HANDLE], AX ;save HANDLE
- MOV AH, 03E ;close file
- INT 021
- MOV BX, 2
- MOV AH, 045
- INT 021
- JMP SHORT A1
-
- FILE_ERROR: MOV DX, OFFSET NO_FILE
- JMP QUIT
-
- OPEN_FILE: MOV DX, SI ;point DX at string
- DEC DX ;remember SI was advanced
- L2: LODSB
- CMP AL, 0D ;CR end of line?
- JE PUT_ZERO
- CMP AL, 020 ;space between parameters?
- JNE L2
- PUT_ZERO: MOV B[SI-1], 0 ;end string with zero, for Asciiz
- MOV AX, 03D00 ;OPEN file for reading
- INT 021
- JC FILE_ERROR
- MOV W[FILE_HANDLE], AX
-
- A1: MOV AH, 0F ;video mode in AL
- INT 010
- CMP AL, 7 ;monochrome 80 x 25
- JE VIDEO_INFO
- CMP AL, 3 ;color text 40 x 25 or 80 x 25
- JBE VIDEO_INFO
- MOV AX, 03 ;force color text if necessary
- INT 010
- VIDEO_INFO: MOV AX, 040 ;BIOS data area
- MOV ES, AX
- ES MOV AX, W[063] ;display card
- MOV W[PORT_ADDRESS], AX
- TEST AL, 020 ;03B4 = mono 03D4 = color
- JZ COLOR ; 1011 0100 1101 0100
- MOV VIDEO_SEG, 0B000 ;mono segment address
- JMP SHORT NO_CGA
- COLOR: MOV AH, 012 ;returns EGA info
- MOV BL, 010
- INT 010
- CMP BL, 010 ;if unchanged, then CGA
- JNE NO_CGA
- MOV CGA_MODE, 1
- NO_CGA: ES MOV AX, W[04E] ;offset to current page
- MOV VIDEO_ADDR, AX
- MOV AH, 0F
- INT 010 ;page in BH, AH = screen width
- MOV B[PAGE_NUM+1], BH
- MOV B[SCR_COLUMNS], AH
- ES MOV AL, B[084] ;character rows on screen
- INC AL
- MOV B[SCR_ROWS], AL
- PUSH CS
- POP ES
-
- MOV AH, 8 ;read screen char (pg in BH)
- INT 010
- MOV B[ATTRIBUTE], AH
- MOV AH, 03 ;find cursor function
- INT 010 ;CH start - CL stop - scan line
- MOV W[USER_CURSOR+1], CX
- MOV AH, 01 ;these 3 lines to remove cursor
- MOV CH, 020 ;blank cursor code
- INT 010
-
- MOV DX, OFFSET ERROR_HANDLE
- MOV AX, 02523
- INT 021
- MOV B[INPUT_COUNT], 0 ;initialize data area at end
- MOV W[LOW_OFFSET], 1
- CALL HOME ;set SI = BUFFER
- A5: LEA BP, BLANK_SCREEN
-
- DISPLAY: CALL SHOW_PAGE
- GET_ASCII: MOV AH, 8 ;get key
- INT 021
- CMP AL, 01B ;ESC
- JE ERROR_HANDLE
- CMP AL, '*'
- JNE GET_SCAN
- XOR B[WORDSTAR+1], 080 ;AND with 07F to turn off high bit
- JMP A5
- GET_SCAN: CMP AL, 0
- JNZ GET_ASCII
- MOV AH, 8
- INT 021
- SUB AL, 047 ;ready for key table
- JB GET_ASCII
- CMP AL, 0C
- JA GET_ASCII
- CBW
- SHL AX, 1 ;double it for WORD table
- MOV BX, AX
- MOV SI, W[PLACE_MARK]
- LEA BP, BLANK_SCREEN
- CALL KEY_TABLE[BX] ;process each key press
- MOV W[PLACE_MARK], SI
- JMP DISPLAY
-
- ERROR_HANDLE:
- USER_CURSOR: MOV CX, 0B0C ; (self modify) restore normal cursor
- MOV AH, 1
- INT 010
- PATCH: MOV BX, W[FILE_HANDLE] ; (self modify) make INT 020 for
- MOV AH, 03E ; redirection, else CLOSE file
- INT 021
- INT 020
-
- KEY_TABLE DW HOME, UP, PGUP, NONE, LEFT, NONE, RIGHT, NONE
- DW ENDY, DOWN, PGDN, DO_SEARCH, SEARCH_AGAIN
- ;ins del
-
- HOME: XOR BX, BX
- MOV AX, W[LOW_OFFSET]
- OR AX, W[HIGH_OFFSET]
- MOV W[LOW_OFFSET], BX
- MOV W[HIGH_OFFSET], BX
- MOV W[SHIFT_RIGHT], BX
- MOV SI, BUFFER
- JZ RET
- MOV DX, BUFFER
- MOV CX, FULL_READ
- CALL READ_FILE
- RET
-
- UP: CALL BACKUP
- JC NONE
- MOV BP, OFFSET NEW_UP
- UP2: CALL BACKUP
- B1: CALL BACKUP ;step back with SI
- JC RET
- CMP AL, 0A
- JNE B1 ;go till find LF
- CALL FORWARD
- RET
-
- ENDY: MOV SI, W[END_BYTE]
- CMP SI, BUFFER_TOP
- JBE PGUP
- CALL FORWARD2
- JMP ENDY
-
- PGUP: MOV CX, W[SCR_ROWS]
- CALL BACKUP
- JC NONE
- B2: CALL UP2
- LOOP B2
- RET
-
- LEFT: CMP W[SHIFT_RIGHT], 0
- MOV W[SHIFT_RIGHT], 0
- JNZ RET
- NONE: POP AX ;get rid of RET address from stack
- JMP GET_ASCII
-
- RIGHT: MOV AL, SHIFT
- CBW
- ADD W[SHIFT_RIGHT], AX
- RET
-
- DOWN: MOV BP, OFFSET NEW_DOWN
- DOWN2: CALL FORWARD
- JC RET
- CMP AL, 0A
- JNE DOWN2
- RET
-
- PGDN: MOV CX, W[SCR_ROWS]
- B4: CALL DOWN2
- LOOP B4
- JC NONE
- RET
-
- SHOW_PAGE: PUSH ES
- MOV SI, W[PLACE_MARK]
- MOV ES, W[VIDEO_SEG]
- CALL BP ;blank screen, scroll up or down
- MOV AL, B[SCR_COLUMNS]
- CBW
- ADD AX, W[SHIFT_RIGHT]
- MOV W[TOTAL_SHIFT], AX
- XOR DL, DL
- B7: XOR BX, BX
- MOV AL, B[SCR_COLUMNS]
- MUL DL
- SHL AX, 1
- MOV DI, AX
- ADD DI, W[VIDEO_ADDR]
- NEXT_LINES: CALL FORWARD ;get char in AL, advance SI
- JC END_PAGE
- WORDSTAR: AND AL, 0FF ;flipflop 0FF & 07F, turn off high bit
- CMP AL, 0D ;CR
- JE NEXT_LINES
- CMP AL, 0A ;LF
- JE NEW_LINE
- CMP AL, 09 ;TAB
- JE TAB
- MOV CX, 1
- C2: CMP BX, W[SHIFT_RIGHT]
- JB C6
- CMP BX, W[TOTAL_SHIFT]
- JAE C6
- MOV AH, B[ATTRIBUTE]
- CMP SI, W[SEARCH_MARK]
- IF E XOR AH, 0F7 ;inverse attribute, blink
- CMP B[CGA_MODE], 0
- JZ C5
- PUSH BX
- PUSH DX
- MOV BX, AX
- MOV DX, W[PORT_ADDRESS]
- ADD DX, 6 ;status register
- HORIZ_RETRACE: IN AL, DX
- SHR AL, 1
- JC HORIZ_RETRACE
- CLI ;Disable interupts.
- WAITER: IN AL, DX
- SHR AL, 1
- JNC WAITER
- MOV AX, BX
- STOSW
- STI ;Enable interupts.
- POP DX
- POP BX
- JMP SHORT C6
- C5: STOSW
- C6: INC BX
- LOOP C2
- JMP NEXT_LINES
- TAB: MOV AX, BX ;adjust column counter
- AND AX, 07 ;get bottom three bits
- MOV CX, 08 ;adjust
- SUB CX, AX
- MOV AL, 020 ;pad spaces
- JMP C2
- NEW_LINE: INC DL
- CMP DL, B[SCR_ROWS]
- JB B7
- END_PAGE: POP ES
- RET
-
- FORWARD: CMP SI, W[END_BYTE]
- JAE D2
- CMP SI, BUFFER_TOP
- JB D1
- FORWARD2: PUSH CX
- PUSH DX
- PUSH DI
- PUSH ES
- PUSH DS
- POP ES
- MOV SI, BUFFER + HALF_READ
- MOV DI, BUFFER
- MOV CX, HALF_READ
- SUB W[PLACE_MARK], CX
- REP MOVSB
- MOV SI, DI
- ADD W[LOW_OFFSET], FULL_READ
- ADC W[HIGH_OFFSET], 0
- MOV DX, BUFFER + HALF_READ
- MOV CX, HALF_READ
- CALL READ_FILE
- SUB W[LOW_OFFSET], HALF_READ
- SBB W[HIGH_OFFSET], 0
- POP ES
- POP DI
- POP DX
- POP CX
- JMP FORWARD
- D1: LODSB
- D2: CMC ;Complement carry flag.
- RET
-
- BACKUP: CMP SI, BUFFER
- JA D3
- MOV AX, W[LOW_OFFSET]
- OR AX, W[HIGH_OFFSET]
- JZ D4
- PUSH CX
- PUSH DX
- MOV SI, BUFFER
- MOV DI, BUFFER + HALF_READ
- MOV CX, HALF_READ
- ADD W[PLACE_MARK], CX
- REP MOVSB
- SUB W[LOW_OFFSET], HALF_READ
- SBB W[HIGH_OFFSET], 0
- MOV DX, BUFFER
- MOV CX, HALF_READ
- CALL READ_FILE
- POP DX
- POP CX
- D3: DEC SI
- MOV AL, B[SI]
- CLC ;Clear the carry flag.
- RET
- D4: STC
- RET
-
- READ_FILE: PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- MOV W[SEARCH_MARK], 0
- MOV W[END_BYTE], 0FFFF
- MOV DX, W[LOW_OFFSET] ;CX:DX offset in file (begin 0)
- MOV CX, W[HIGH_OFFSET]
- MOV BX, W[FILE_HANDLE]
- MOV AX, 04200 ;set file read pointer
- INT 021
- POP DX
- POP CX
- MOV AH, 03F ;read file
- INT 021
- JNC D5
- XOR AX, AX
- D5: CMP AX, CX ;bytes read
- JE D6
- ADD AX, DX
- MOV W[END_BYTE], AX
- D6: POP BX
- POP AX
- RET
-
- BLANK_SCREEN: MOV AX, 0600
- JMP SHORT D8
-
- NEW_UP: MOV AH, 07
- JMP SHORT D7
-
- NEW_DOWN: MOV AH, 06
- D7: MOV AL, 1
- D8: XOR CX, CX ;top left corner 0, 0
- MOV DL, B[SCR_COLUMNS]
- DEC DL
- MOV DH, B[SCR_ROWS] ;DX lower right corner 24, 79
- DEC DH
- MOV BH, B[ATTRIBUTE]
- INT 010
- RET
-
- DO_SEARCH: MOV AX, 0920 ;write without moving the cursor
- PAGE_NUM: MOV BH, 0 ;(self modify) active display page
- MOV BL, B[ATTRIBUTE]
- MOV CX, 60 ;# of chars for buffer is 60
- INT 010
- MOV AX, 0E BY '?' ;TTY write of question mark
- INT 010
- MOV CX, 010C ;block cursor
- MOV AH, 1
- INT 010
-
- MOV W[INPUT_SIZE], 61 ;INPUT_SIZE = 61, INPUT_COUNT = 0
- MOV DX, OFFSET INPUT_SIZE
- MOV AH, 0A ;get buffered keyboard input
- INT 021
- MOV AH, 01 ;these 3 lines to remove cursor
- MOV CH, 020 ;blank cursor code
- INT 010
- CMP B[INPUT_COUNT], 0
- JZ RET
- CALL HOME ;SI at buffer
- JMP SHORT SET_UP
-
- SEARCH_AGAIN: CMP B[INPUT_COUNT], 0
- IF Z JMP NONE
- CALL DOWN2
- CALL DOWN2
- JMP SHORT SET_UP
-
- READ_MORE: CMP W[END_BYTE], 0FFFF ;middle of file?
- JNE SEARCH_DONE
- CALL FORWARD2
- DEC SI
- SET_UP: MOV DI, SI ;DI in file
- MOV SI, OFFSET INPUT ;SI at search entry
- LODSB ;AL first character for search
- MOV CX, W[END_BYTE]
- CMP CX, BUFFER_TOP
- IF A MOV CX, BUFFER_TOP
- SUB CX, DI ;CX bytes to search
-
- FIND_MATCH: REPNE SCASB
- JCXZ READ_MORE
- PUSH CX ;first character matches
- PUSH DI
- PUSH SI
- MOV CL, B[INPUT_COUNT]
- XOR CH, CH
- DEC CL
- REPE CMPSB ;compare with search input
- POP SI
- POP DI
- POP CX
- JNE FIND_MATCH
- MOV W[SEARCH_MARK], DI ;record position
- SEARCH_DONE: MOV SI, DI
- CALL UP2
- CALL UP2
- LAST: RET
-
- DATA SEGMENT
- ORG OFFSET LAST+1
-
- ATTRIBUTE DB ?
- SCR_COLUMNS DB ?
- PORT_ADDRESS DW ?
- LOW_OFFSET DW ?
- HIGH_OFFSET DW ?
- SHIFT_RIGHT DW ?
- TOTAL_SHIFT DW ?
- FILE_HANDLE DW ?
- END_BYTE DW ?
- SEARCH_MARK DW ?
-
- INPUT_SIZE DB ? ;buffered keyboard input, 1st byte buffer size
- INPUT_COUNT DB ? ;next byte = number of characters read
- INPUT DB 61 DUP ? ;buffer for 60 characters (plus CR)
-
- DATA ENDS
-